package com.sdleyou.treepro.common.service.impl;

import com.sdleyou.treepro.common.exception.ServiceException;
import com.sdleyou.treepro.common.model.convert.AppointmentDO2AppointmentVOConverter;
import com.sdleyou.treepro.common.model.dao.*;
import com.sdleyou.treepro.common.model.enums.ErrorCodeEnum;
import com.sdleyou.treepro.common.model.utils.RandomUtil;
import com.sdleyou.treepro.common.model.vo.AppointActiveVO;
import com.sdleyou.treepro.common.model.vo.AppointmentVO;
import com.sdleyou.treepro.common.service.AppointmentManager;
import com.sdleyou.treepro.common.service.MongoPageManager;
import com.sdleyou.treepro.common.utils.DateUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AppointmentManagerImpl implements AppointmentManager {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private MongoPageManager mongoPageManager;

    @Override
    public List<AppointActiveVO> getAppointmentActive(String baseId) {
        Query query = new Query();
        Criteria c = Criteria.where("status").is("SHOW").and("base_id").is(baseId);
        Sort sort = Sort.by(Sort.Direction.ASC, "begin");
        query.addCriteria(c).with(sort);
        List<AppointActiveDO> activeDOList = mongoTemplate.find(query, AppointActiveDO.class);
        List<AppointActiveVO> activeVOList = new ArrayList<>();
        for (AppointActiveDO activeDO : activeDOList) {
            AppointActiveVO activeVO = new AppointActiveVO();
            BeanUtils.copyProperties(activeDO, activeVO);
            Query queryAppoint = new Query(Criteria.where("active_id").is(activeDO.getActiveId()));
            long current = mongoTemplate.count(queryAppoint, AppointmentDO.class);
            activeVO.setCurrent((int) current);
            activeVOList.add(activeVO);
        }
        return activeVOList;
    }

    @Override
    public void makeAppointment(String userId, String activeId, String orderTime, String wellId) {
        Query queryUser = new Query(Criteria.where("user_id").is(userId));
        UserDO userDO = mongoTemplate.findOne(queryUser, UserDO.class);
        if (userDO == null) {
            throw new ServiceException(ErrorCodeEnum.E100.code(), ErrorCodeEnum.E100.getDescription());
        }

        //预约
        Query perWell = new Query(Criteria.where("well_id").is(wellId));
        WellDO perWellDO = mongoTemplate.findOne(perWell, WellDO.class);
        if (perWellDO.getOrderStatus() == null || !perWellDO.getOrderStatus().equals(0)) {
            throw new ServiceException(ErrorCodeEnum.E029.code(), ErrorCodeEnum.E029.getDescription());
        }
        String treeName = perWellDO.getPreTreeName();

        //活动是否存在
        Query queryActive = new Query(Criteria.where("active_id").is(activeId).and("status").is("SHOW"));
        AppointActiveDO activeDO = mongoTemplate.findOne(queryActive, AppointActiveDO.class);
        if (activeDO == null) {
            throw new ServiceException(ErrorCodeEnum.E024.code(), ErrorCodeEnum.E024.getDescription());
        }
        if (!perWellDO.getBaseId().equals(activeDO.getBaseId())) {
            throw new ServiceException(ErrorCodeEnum.E030.code(), ErrorCodeEnum.E030.getDescription());
        }
        //活动是否预约满
        Query queryAppoint = new Query(Criteria.where("active_id").is(activeDO.getActiveId()));
        long current = mongoTemplate.count(queryAppoint, AppointmentDO.class);
        if (current >= activeDO.getEstimate()) {
            throw new ServiceException(ErrorCodeEnum.E025.code(), ErrorCodeEnum.E025.getDescription());
        }
        //可以预约
        AppointmentDO appointmentDO = new AppointmentDO();
        appointmentDO.setActiveId(activeDO.getActiveId());
        appointmentDO.setAppointmentId(RandomUtil.randomId());
        appointmentDO.setUserId(userId);
        appointmentDO.setRealName(userDO.getRealName());
        appointmentDO.setNickname(userDO.getNickname());
        appointmentDO.setFace(userDO.getFace());
        appointmentDO.setOrderTime(orderTime);
        appointmentDO.setMobile(userDO.getPhone());
        appointmentDO.setStatus("WAITING");
        appointmentDO.setTreeName(treeName);
        appointmentDO.setGmtCreate(DateUtil.getDateline());
        appointmentDO.setGmtModified(DateUtil.getDateline());
        mongoTemplate.insert(appointmentDO);

        Update update = new Update();
        update.set("order_status", 1);
        update.set("appointment_id", appointmentDO.getAppointmentId());
        mongoTemplate.updateFirst(perWell, update, WellDO.class);

        return;
    }

    @Override
    public Page<AppointmentVO> myAppointment(String userId, Integer pageSize, Integer pageNum) {
        Query query = new Query();
        Criteria c = Criteria.where("user_id").is(userId);
        Sort sort = Sort.by(Sort.Direction.DESC, "begin");
        query.addCriteria(c).with(sort);
        Page<AppointmentDO> page = mongoPageManager.pageQuery(query, AppointmentDO.class, pageSize, pageNum);
        List<AppointmentDO> appointmentDOList = page.getData();
        List<AppointmentVO> voList = appointmentDOList.stream().map(e -> AppointmentDO2AppointmentVOConverter.convert(e)).collect(Collectors.toList());

        return new Page<>(page.getPageNo(), page.getDataTotal(), page.getPageSize(), voList);
    }

    @Override
    public void cancelAppointment(String userId, String appointmentId) {
//        Query query = new Query(Criteria.where("user_id").is(userId).and("appointment_id").is(appointmentId));
//        AppointmentDO appointmentDO = mongoTemplate.findOne(query, AppointmentDO.class);
//        if (appointmentDO == null) {
//            throw new ServiceException(ErrorCodeEnum.E027.code(), ErrorCodeEnum.E027.getDescription());
//        }
//        if (appointmentDO.getStatus().equals("DONE")) {
//            throw new ServiceException(ErrorCodeEnum.E028.code(), ErrorCodeEnum.E028.getDescription());
//        }
//        mongoTemplate.remove(query, AppointmentDO.class);
        return;
    }
}
